package com.chaos.auth.config.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class AuthenticationSuccessHandler implements org.springframework.security.web.authentication.AuthenticationSuccessHandler {

    private final ObjectMapper objectMapper;

    public AuthenticationSuccessHandler(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        if (authentication instanceof OAuth2AccessTokenAuthenticationToken oauth2Authentication) {
            Map<String, Object> data = new HashMap<>();
            OAuth2AccessToken accessToken = oauth2Authentication.getAccessToken();

            // 添加 访问令牌 和 令牌类型
            data.put("access_token", accessToken.getTokenValue());
            data.put("token_type", accessToken.getTokenType().getValue());
            // 过期时间
            if (accessToken.getExpiresAt() != null) {
                data.put("expires_in", ChronoUnit.SECONDS.between(Instant.now(), accessToken.getExpiresAt()));
            }
            // 刷新令牌
            OAuth2RefreshToken refreshToken = oauth2Authentication.getRefreshToken();
            if (refreshToken != null) {
                data.put("refresh_token", refreshToken.getTokenValue());
            }
            // 客户端权限范围
            if (!accessToken.getScopes().isEmpty()) {
                data.put("scope", accessToken.getScopes());
            }
            // id_token
            Map<String, Object> additionalParameters = oauth2Authentication.getAdditionalParameters();
            if (additionalParameters.containsKey("id_token")) {
                data.put("id_token", additionalParameters.get("id_token"));
            }
            // 用户权限
            if (additionalParameters.containsKey("authorities")) {
                data.put("authorities", additionalParameters.get("authorities"));
            }

            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            objectMapper.writeValue(response.getWriter(), data);
        }
    }

}
